#include "AAAPack.h"
#include <arpa/inet.h>
#include <string.h>
#include <iostream>


EMsgCode AAAPack::code() const
{
    return _code;
}

void AAAPack::setCode(const EMsgCode &code)
{
    _code = code;
}

void AAAPack::addAttr( EAttrType type, const void* data, uint16_t dataLen )
{
    AAAAttrbute attr;
    attr.setType( type );
    attr.setVal( data, dataLen );
    _attrs.push_back( attr );
    _length += attr.length();
}

std::string AAAPack::scret() const
{
    return _scret;
}

void AAAPack::setScret(const std::string &scret)
{
    _scret = scret;
}

uint8_t AAAPack::identifier() const
{
    return _identifier;
}

void AAAPack::setIdentifier(const uint8_t &identifier)
{
    _identifier = identifier;
}


std::array<uint8_t, 16> AAAPack::authenticator() const
{
    return _authenticator;
}

void AAAPack::setAuthenticator(const std::array<uint8_t, 16> &authenticator)
{
    _authenticator = authenticator;
}


bool AAAPack::pack(uint8_t *&data, uint8_t &dataLen)
{
    if ( _code == EMsgCode::CODE_NONE )
    {
        return false;
    }
    //申请内存
    std::shared_ptr<uint8_t> ptmp( new uint8_t[_length] );
    _pbuf =  ptmp;
    //方便填充数据
    struct SMsgPack* pmsg = ( struct SMsgPack*)_pbuf.get();
    //填充数据
    pmsg->codePlace = static_cast<uint8_t>(_code);
    pmsg->identifier = _identifier;
    //不是网络字节序
    pmsg->length = ::htons( _length );
    ::memcpy(  pmsg->authenticatior,_authenticator.data(),_authenticator.max_size() );

    //属性从认证字后面开始

    uint8_t* pstart = (uint8_t*)_pbuf.get();
    pstart += sizeof( struct SMsgPack );

    for( auto&i : _attrs )
    {
        uint8_t *attrData = nullptr;
        uint8_t len = 0;
        if ( !i.pack( attrData,len ) )
        {
            return false;
        }
        ::memcpy(  pstart,attrData, len );
        pstart += len;
    }
    data = _pbuf.get();
    dataLen = _length;
    return true;
}


